package com.zimin.cloud.user.biz.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zimin.cloud.mine.pojo.user.business.UserBO;
import com.zimin.cloud.mine.pojo.user.business.UserInfoBO;
import com.zimin.cloud.mine.pojo.user.view.UserInfoVO;
import com.zimin.cloud.mine.pojo.user.view.UserVO;
import com.zimin.cloud.user.biz.IRefreshTokenBiz;
import com.zimin.cloud.user.biz.IUserBiz;
import com.zimin.cloud.user.biz.IUserInfoBiz;
import com.zimin.cloud.user.biz.IUserRoleBiz;
import com.zimin.cloud.user.common.constant.UserConstants;
import com.zimin.cloud.user.common.util.TokenUtil;
import com.zimin.cloud.user.pojo.entity.RefreshToken;
import com.zimin.cloud.user.pojo.entity.User;
import com.zimin.cloud.user.pojo.entity.UserInfo;
import com.zimin.cloud.user.service.impl.UserServiceImpl;
import com.zimin.common.annotation.Biz;
import com.zimin.common.constant.StringPool;
import com.zimin.common.exception.GraceException;
import com.zimin.common.utils.*;
import com.zimin.shared.enums.ResponseStatusEnum;
import com.zimin.shared.pojo.PageVO;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.Map;


/**
 * <p>
 * 用户表 业务对象
 * </p>
 *
 * @author zimin
 * @since 2022-06-14 15:53
 */
@Biz("userBiz")
public class UserBizImpl extends UserServiceImpl implements IUserBiz {

    @Autowired
    private UserConstants userConstants;
    @Autowired
    private IUserInfoBiz userInfoBiz;
    @Autowired
    private IUserRoleBiz userRoleBiz;
    @Autowired
    private IRefreshTokenBiz refreshTokenBiz;

    @Override
    public boolean addUser(UserBO userBO) {
        var phone = userBO.getPhone();
        var userVO = super.getUserByPhone(phone);
        GraceException.isNotNull(userVO, ResponseStatusEnum.USER_PHONE_IS_EXIST);
        var salt = IdUtils.simpleUUID();
        var user = new User();
        //前端加密处理之后的值
        var password = user.getPassword();
        //明文密码
        var rawPassword = "";
        try {
            rawPassword = RSAUtil.decrypt(password);
        } catch (Exception e) {
            GraceException.display(ResponseStatusEnum.PASSWORD_RSA_ERROR);
        }
        var md5Password = Md5Util.sign(rawPassword, salt, StringPool.UTF_8);
        user.setSalt(salt);
        user.setPassword(md5Password);
        var saveUserFlag = super.save(user);
        GraceException.isFalse(saveUserFlag, ResponseStatusEnum.USER_REGISTER_ERROR);
        //添加用户信息
        var userInfo = UserInfo.builder()
                .nick(userConstants.getNick())
                .birth(userConstants.getBirth())
                .gender(userConstants.getGender()).build();
        userInfo.setId(user.getId());
        var flag = userInfoBiz.save(userInfo);
        userRoleBiz.addUserDefaultUser(user.getId());
        return flag;
    }

    @Override
    public String login(UserBO userBO) throws Exception {
        var phone = userBO.getPhone();
        var userVO = super.getUserByPhone(phone);
        GraceException.isNull(userVO, ResponseStatusEnum.USER_PHONE_IS_NOT_EXIST);
        //明文密码
        String password = userBO.getPassword();
        String rawPassword = "";
        try {
            rawPassword = RSAUtil.decrypt(password);
        } catch (Exception e) {
            GraceException.display(ResponseStatusEnum.PASSWORD_RSA_ERROR);
        }
        var salt = userVO.getSalt();
        var md5Password = Md5Util.sign(rawPassword, salt, StringPool.UTF_8);
        GraceException.isFalse(md5Password.equals(userVO.getPassword()), ResponseStatusEnum.PASSWORD_ERROR);
        //返回登录凭证
        return TokenUtil.generateToken(userVO.getId());
    }

    @Override
    public UserVO getUserInfo(String userId) {
        var user = super.getById(userId, UserVO.class);
        var userInfo = userInfoBiz.getById(userId, UserInfoVO.class);
        user.setUserInfo(userInfo);
        return user;
    }

    @Override
    public boolean updateUserInfos(UserInfoBO userInfoBO) {
        var userInfo = BeanUtils.coverClass(userInfoBO, UserInfo.class);
        return userInfoBiz.updateById(userInfo);
    }

    @Override
    public PageVO<UserInfoVO> pageListUserInfos(Page<UserInfo> page, UserInfoBO userInfoBO) {
        Page<UserInfo> pageResult = userInfoBiz.lambdaQuery()
                .like(StringUtils.isNotEmpty(userInfoBO.getNick()), UserInfo::getNick, userInfoBO.getNick())
                .page(page);
        return pageToPageVO(pageResult, BeanUtils.listEntityToView(pageResult.getRecords(), UserInfoVO.class));
    }

    @Override
    public Map<String, Object> loginForDts(UserBO userBO) throws Exception {
        var phone = userBO.getPhone();
        var userVO = super.getUserByPhone(phone);
        GraceException.isNotNull(userVO, ResponseStatusEnum.USER_PHONE_IS_EXIST);
        var salt = IdUtils.simpleUUID();
        var user = new User();
        //前端加密处理之后的值
        var password = user.getPassword();
        //明文密码
        var rawPassword = "";
        try {
            rawPassword = RSAUtil.decrypt(password);
        } catch (Exception e) {
            GraceException.display(ResponseStatusEnum.PASSWORD_RSA_ERROR);
        }
        var md5Password = Md5Util.sign(rawPassword, salt, StringPool.UTF_8);
        user.setSalt(salt);
        user.setPassword(md5Password);
        var saveUserFlag = super.save(user);
        GraceException.isFalse(saveUserFlag, ResponseStatusEnum.USER_REGISTER_ERROR);
        var accessToken = TokenUtil.generateToken(user.getId());
        var refreshToken = TokenUtil.generateRefreshToken(user.getId());
        refreshTokenBiz.remove(Wrappers.<RefreshToken>lambdaQuery().eq(RefreshToken::getRefreshToken, refreshToken));
        RefreshToken r = RefreshToken.builder().refreshToken(refreshToken).userId(user.getId()).build();
        refreshTokenBiz.save(r);
        var result = new HashMap<String, Object>();
        result.put("refreshToken", refreshToken);
        result.put("accessToken", accessToken);
        return result;
    }

    @Override
    public void logout(String refreshToken, String userId) {
        refreshTokenBiz.remove(Wrappers.<RefreshToken>lambdaQuery().eq(RefreshToken::getRefreshToken, refreshToken));
    }

    @Override
    public String refreshAccessToken(String refreshToken) throws Exception {
        return TokenUtil.generateToken("");
    }

}
